package org.demo.szml.userservice.controller;

import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.demo.szml.api.response.Response;
import org.demo.szml.api.response.ResponseCode;
import org.demo.szml.userservice.controller.dto.*;
import org.demo.szml.userservice.controller.vo.*;
import org.demo.szml.userservice.service.IUserService;
import org.demo.szml.userservice.service.result.UserInfoHandleResult;
import org.demo.szml.userservice.service.result.UserLoginHandleResult;
import org.demo.szml.userservice.service.result.UserModifyInfoHandleResult;
import org.demo.szml.userservice.service.result.UserRegisterHandleResult;
import org.demo.szml.userservice.utils.JwtUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import java.util.List;
import java.util.stream.Collectors;

import static org.demo.szml.userservice.utils.IPGetUtil.getClientIp;

/**
 * @description: 用户功能控制器
 * @date: 2025/6/12 22:23
 * @version: 1.0
 */
@RestController
@RequestMapping("/user")
public class UserController {

    //引入用户服务
    private final IUserService userService;



    public UserController(IUserService userService){
        this.userService = userService;
    }

    @PostMapping("/register")
    public Response<UserRegisterVO> register(@Valid @RequestBody UserRegisterDTO registerDTO,
                                             HttpServletRequest httpServletRequest){
        //获取客户端IP
        String clientIp = getClientIp(httpServletRequest);
        //设置IP
        registerDTO.setClientIp(clientIp);
        //进行注册逻辑处理
        UserRegisterHandleResult registerHandleResult = userService.register(registerDTO);
        //业务流程没有已知异常
        if(registerHandleResult.isHandleSuccess()){
            StpUtil.login(registerHandleResult.getUserId());
            return Response.<UserRegisterVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserRegisterVO.builder().userId(registerHandleResult.getUserId())
                            .token(StpUtil.getTokenInfo().tokenValue).build()).build();
        }
        //返回提示信息
        return Response.<UserRegisterVO>builder().code(ResponseCode.REASON_FAILED).info(registerHandleResult.getExtInfo()).build();
    }

    @PostMapping("/login")
    public Response<UserLoginVO> login(@Valid @RequestBody UserLoginDTO userLoginDTO,
                                       HttpServletRequest servletRequest){
        //获取客户端IP
        String ip = getClientIp(servletRequest);
        userLoginDTO.setClientIp(ip);
        //执行登录操作
        UserLoginHandleResult login = userService.login(userLoginDTO);
        //执行成功
        if(login.isHandleSuccess()){
            //存放到SA-Token中去
            StpUtil.login(login.getUserId());
            return Response.<UserLoginVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserLoginVO.builder().userId(login.getUserId()).username(login.getUsername())
                            .jwtToken(StpUtil.getTokenInfo().tokenValue).build()).build();
        }
        //执行失败
        return Response.<UserLoginVO>builder().code(ResponseCode.REASON_FAILED).info(login.getExtInfo()).build();
    }

    @GetMapping("/{userId}")
    public Response<UserInfoVO> getUserById(@PathVariable("userId") Long userId,
                                            HttpServletRequest request){
        if (!StpUtil.isLogin()) {
            return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info("请登录后重试").build();
        }
        UserSelectDTO selectDTO = UserSelectDTO.builder().userId(userId).build();
        //设置ip和操作人信息
        selectDTO.setClientIp(getClientIp(request));
        selectDTO.setOperatorId(StpUtil.getLoginIdAsLong());
        UserInfoHandleResult userInfo = userService.selectUserById(selectDTO);
        if(userInfo.isHandleSuccess()){
            return Response.<UserInfoVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserInfoVO.builder().username(userInfo.getUsername())
                            .password(userInfo.getPassword())
                            .phone(userInfo.getPhone())
                            .email(userInfo.getEmail())
                            .userId(userInfo.getUserId())
                            .roleDescription(userInfo.getRoleDescription())
                            .build()).build();
        }
        return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info(userInfo.getExtInfo()).build();
    }

    @GetMapping("/users")
    public Response<PageVO<UserInfoVO>> getUsers(@RequestParam(name = "page",defaultValue = "1")  Integer page,
                                                 @RequestParam(name = "size",defaultValue = "10") @Max(value = 100,message = "每页数量不能大于100条") Integer size,
                                                 HttpServletRequest request){
        if(!StpUtil.isLogin()){
            return Response.<PageVO<UserInfoVO>>builder().code(ResponseCode.REASON_FAILED).info("请登录后重试").build();
        }
        UserSelectDTO selectDTO = UserSelectDTO.builder().page(page).size(size).build();
        selectDTO.setClientIp(getClientIp(request));
        selectDTO.setOperatorId(StpUtil.getLoginIdAsLong());
        Page<UserInfoHandleResult> userInfos = userService.pageUsers(selectDTO);
        if(ObjectUtils.isEmpty(userInfos.getRecords())){
            return Response.<PageVO<UserInfoVO>>builder().code(ResponseCode.SUCCESS).data(PageVO.empty()).build();
        }
        List<UserInfoVO> collect = userInfos.getRecords().stream().map(userInfo -> UserInfoVO.builder().username(userInfo.getUsername())
                .password(userInfo.getPassword())
                .phone(userInfo.getPhone())
                .email(userInfo.getEmail())
                .userId(userInfo.getUserId())
                .roleDescription(userInfo.getRoleDescription())
                .build()).collect(Collectors.toList());
        return Response.<PageVO<UserInfoVO>>builder().code(ResponseCode.SUCCESS)
                .data(PageVO.of(collect, userInfos.getTotal())).build();
    }

    @PutMapping("/{userId}")
    public Response<UserInfoVO> modifyUserInfo(@PathVariable("userId") Long userId,
                                                     @RequestBody UserModifyInfoDTO modifyInfo,
                                                     HttpServletRequest request){
        if(!StpUtil.isLogin()){
            return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info("请登录后重试").build();
        }
        modifyInfo.setUserId(userId);
        modifyInfo.setClientIp(getClientIp(request));
        modifyInfo.setOperatorId(StpUtil.getLoginIdAsLong());
        UserModifyInfoHandleResult modifyInfoHandleResult = userService.modifyUserInfo(modifyInfo);
        if(modifyInfoHandleResult.isHandleSuccess()){
            return Response.<UserInfoVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserInfoVO.builder().userId(userId).build()).build();
        }
        return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info(modifyInfoHandleResult.getExtInfo()).build();
    }

    @PostMapping("/reset-password")
    public Response<UserInfoVO> resetPassword(@RequestBody UserResetPwdDTO resetPwdDTO,
                                                    HttpServletRequest request){
        if(!StpUtil.isLogin()){
            return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info("请登录后重试").build();
        }
        resetPwdDTO.setClientIp(getClientIp(request));
        resetPwdDTO.setOperatorId(StpUtil.getLoginIdAsLong());
        UserModifyInfoHandleResult modifyInfoHandleResult = userService.resetPassword(resetPwdDTO);
        if(modifyInfoHandleResult.isHandleSuccess()){
            return Response.<UserInfoVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserInfoVO.builder().userId(resetPwdDTO.getUserId()).build()).build();
        }
        return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info(modifyInfoHandleResult.getExtInfo()).build();
    }

    @PostMapping("/rebind/role")
    public Response<UserInfoVO> rebindRole(@RequestBody UserRebindDTO rebindDTO,
                                                 HttpServletRequest request){
        if (!StpUtil.isLogin()){
            return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info("请登录后重试").build();
        }
        rebindDTO.setClientIp(getClientIp(request));
        rebindDTO.setOperatorId(StpUtil.getLoginIdAsLong());
        UserModifyInfoHandleResult modifyInfoHandleResult = userService.rebindRole(rebindDTO);
        if(modifyInfoHandleResult.isHandleSuccess()){
            return Response.<UserInfoVO>builder().code(ResponseCode.SUCCESS)
                    .data(UserInfoVO.builder().userId(rebindDTO.getUserId()).build()).build();
        }
        return Response.<UserInfoVO>builder().code(ResponseCode.REASON_FAILED).info(modifyInfoHandleResult.getExtInfo()).build();
    }



}
